# -*- coding: utf-8 -*-
import logging
import json
from enum import Enum, unique

from tencentcloud.common import credential
from tencentcloud.common.exception.tencent_cloud_sdk_exception import (
    TencentCloudSDKException,
)

# 导入对应产品模块的client models。
from tencentcloud.sms.v20210111 import sms_client, models

from django.core.cache import cache

from django.conf import settings

from app_common import (
    app_except,
)


@unique
class SMS_TYPE(Enum):
    RECHARGE = "充值"
    CONSUME = "消费"


logger = logging.getLogger("log")


@app_except.app_try
def send_sms_remain_money_change(receiver, change_type, change_money, remain_money):
    """
    发送短信
    https://cloud.tencent.com/document/product/382/43196#.E9.80.9A.E8.BF.87-pip-.E5.AE.89.E8.A3.85.EF.BC.88.E6.8E.A8.E8.8D.90.EF.BC.89
    """
    if not settings.SMS_ENABLE:
        logger.info("sms is disable")
        return

    remain_money = int(int(remain_money) / 100)
    change_money = int(int(change_money) / 100)
    change_info = f"{change_type}{change_money}"
    if len(str(receiver)) > 11:
        raise app_except.ValueErr(msg="receiver too long")
    if len(change_info) > 8:
        raise app_except.ValueErr(msg="change_info too long")
    if len(str(remain_money)) > 6:
        raise app_except.ValueErr(msg="remain_money too long")

    receiver_sms_count = f"{receiver}_sms_count"
    send_count = cache.get(receiver_sms_count, 0)
    # 8小时 不得重复发送 超过 5次
    if send_count > 5:
        logger.error(f"{receiver} send too many sms.")
        return
    cache.set(receiver_sms_count, int(send_count) + 1, 28800)

    secretId = settings.SMS_SECRET_ID
    secretKey = settings.SMS_SECRET_KEY

    cred = credential.Credential(secretId, secretKey)

    # 地域选择，北京最近
    client = sms_client.SmsClient(cred, "ap-beijing")

    # 实例化一个请求对象，根据调用的接口和实际情况，可以进一步设置请求参数
    # 你可以直接查询SDK源码确定SendSmsRequest有哪些属性可以设置
    # 属性可能是基本类型，也可能引用了另一个数据结构
    # 推荐使用IDE进行开发，可以方便的跳转查阅各个接口和数据结构的文档说明
    req = models.SendSmsRequest()

    # 基本类型的设置:
    # SDK采用的是指针风格指定参数，即使对于基本类型你也需要用指针来对参数赋值。
    # SDK提供对基本类型的指针引用封装函数
    # 帮助链接：
    # 短信控制台: https://console.cloud.tencent.com/smsv2
    # 腾讯云短信小助手: https://cloud.tencent.com/document/product/382/3773#.E6.8A.80.E6.9C.AF.E4.BA.A4.E6.B5.81

    # 短信应用ID: 短信SdkAppId在 [短信控制台] 添加应用后生成的实际SdkAppId，示例如1400006666
    # 应用 ID 可前往 [短信控制台](https://console.cloud.tencent.com/smsv2/app-manage) 查看
    req.SmsSdkAppId = settings.SMS_SDK_APP_ID
    # 短信签名内容: 使用 UTF-8 编码，必须填写已审核通过的签名
    # 签名信息可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-sign) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-sign) 的签名管理查看
    req.SignName = settings.SMS_SIGN_NAME
    # 模板 ID: 必须填写已审核通过的模板 ID
    # 模板 ID 可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-template) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-template) 的正文模板管理查看
    req.TemplateId = settings.SMS_TEMPLATE_ID
    # 模板参数: 模板参数的个数需要与 TemplateId 对应模板的变量个数保持一致，，若无模板参数，则设置为空
    # 尊贵的皇家形象会员，尾号{1},{2}, 余额{3}.
    req.TemplateParamSet = [
        str(receiver[-4:]),
        str(change_info),
        str(remain_money),
    ]
    # 下发手机号码，采用 E.164 标准，+[国家或地区码][手机号]
    # 示例如：+8613711112222， 其中前面有一个+号 ，86为国家码，13711112222为手机号，最多不要超过200个手机号
    req.PhoneNumberSet = [f"+86{receiver}"]
    # 用户的 session 内容（无需要可忽略）: 可以携带用户侧 ID 等上下文信息，server 会原样返回
    req.SessionContext = ""
    # 短信码号扩展号（无需要可忽略）: 默认未开通，如需开通请联系 [腾讯云短信小助手]
    req.ExtendCode = ""
    # 国际/港澳台短信 senderid（无需要可忽略）: 国内短信填空，默认未开通，如需开通请联系 [腾讯云短信小助手]
    req.SenderId = ""

    resp = client.SendSms(req)

    # 输出json格式的字符串回包
    body = json.loads(resp.to_json_string())

    ok = body.get("SendStatusSet", [{}])[0].get("Code", None)
    if not ok:
        logger.error(
            f"send sms fail: receiver: {receiver}, change_info: {change_info}, remain_money: {remain_money}"
        )
    # {
    # "SendStatusSet": [
    #     {
    #     "SerialNo": "3369:138869200016825251987552967",
    #     "PhoneNumber": "+8618231129677",
    #     "Fee": 2,
    #     "SessionContext": "",
    #     "Code": "Ok",
    #     "Message": "send success",
    #     "IsoCode": "CN"
    #     }
    # ],
    # "RequestId": "96189835-4dd6-43fd-ae1d-9a6e84c1589e"
    # }

    # 当出现以下错误码时，快速解决方案参考
    # - [FailedOperation.SignatureIncorrectOrUnapproved](https://cloud.tencent.com/document/product/382/9558#.E7.9F.AD.E4.BF.A1.E5.8F.91.E9.80.81.E6.8F.90.E7.A4.BA.EF.BC.9Afailedoperation.signatureincorrectorunapproved-.E5.A6.82.E4.BD.95.E5.A4.84.E7.90.86.EF.BC.9F)
    # - [FailedOperation.TemplateIncorrectOrUnapproved](https://cloud.tencent.com/document/product/382/9558#.E7.9F.AD.E4.BF.A1.E5.8F.91.E9.80.81.E6.8F.90.E7.A4.BA.EF.BC.9Afailedoperation.templateincorrectorunapproved-.E5.A6.82.E4.BD.95.E5.A4.84.E7.90.86.EF.BC.9F)
    # - [UnauthorizedOperation.SmsSdkAppIdVerifyFail](https://cloud.tencent.com/document/product/382/9558#.E7.9F.AD.E4.BF.A1.E5.8F.91.E9.80.81.E6.8F.90.E7.A4.BA.EF.BC.9Aunauthorizedoperation.smssdkappidverifyfail-.E5.A6.82.E4.BD.95.E5.A4.84.E7.90.86.EF.BC.9F)
    # - [UnsupportedOperation.ContainDomesticAndInternationalPhoneNumber](https://cloud.tencent.com/document/product/382/9558#.E7.9F.AD.E4.BF.A1.E5.8F.91.E9.80.81.E6.8F.90.E7.A4.BA.EF.BC.9Aunsupportedoperation.containdomesticandinternationalphonenumber-.E5.A6.82.E4.BD.95.E5.A4.84.E7.90.86.EF.BC.9F)
    # - 更多错误，可咨询[腾讯云助手](https://tccc.qcloud.com/web/im/index.html#/chat?webAppId=8fa15978f85cb41f7e2ea36920cb3ae1&title=Sms)
